using AutoMapper;
using B.S.XZYData.Api.Read.Application.Command.WorkOrder;
using B.S.XZYData.Api.Read.Dto.Plan;
using B.S.XZYData.Api.Read.Dto.WorkOrder;
using B.S.XZYData.Domain.LJC;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.XZYData.Api.Read.Application.Handler.WorkOrder
{
    /// <summary>
    /// 获取工单综合信息处理器
    /// </summary>
    public class GetWorkOrderComprehensiveInfoHandler : IRequestHandler<GetWorkOrderComprehensiveInfoCommand, ApiResult<WorkOrderComprehensiveInfoDto>>
    {
        private readonly IBaseRepository<WorkOrderModel> _workOrderRepo;
        private readonly IBaseRepository<WorkOrderProcessModel> _workOrderProcessRepo;
        private readonly IBaseRepository<WorkOrderAssignModel> _workOrderAssignRepo;
        private readonly IBaseRepository<PlanItemModel> _planItemRepo;
        private readonly IMapper _mapper;

        public GetWorkOrderComprehensiveInfoHandler(
            IBaseRepository<WorkOrderModel> workOrderRepo,
            IBaseRepository<WorkOrderProcessModel> workOrderProcessRepo,
            IBaseRepository<WorkOrderAssignModel> workOrderAssignRepo,
            IBaseRepository<PlanItemModel> planItemRepo,
            IMapper mapper)
        {
            _workOrderRepo = workOrderRepo;
            _workOrderProcessRepo = workOrderProcessRepo;
            _workOrderAssignRepo = workOrderAssignRepo;
            _planItemRepo = planItemRepo;
            _mapper = mapper;
        }

        public async Task<ApiResult<WorkOrderComprehensiveInfoDto>> Handle(GetWorkOrderComprehensiveInfoCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<WorkOrderComprehensiveInfoDto>();

            try
            {
                // 1. 获取工单信息
                var workOrder = _workOrderRepo.GetAll()
                    .Where(x => x.Id == request.WorkOrderId).ToList().FirstOrDefault();

                if (workOrder == null)
                {
                    res.Code = ApiEnum.Error;
                    res.Msg = "工单不存在";
                    return res;
                }

                // 2. 获取关联的计划明细信息
                PlanItemModel? planItem = null;
                if (workOrder.PlanItemId.HasValue)
                {
                    planItem = _planItemRepo.GetAll()
                        .Where(x => x.Id == workOrder.PlanItemId.Value).ToList().FirstOrDefault();
                }

                // 3. 获取工单工序列表
                var processes = _workOrderProcessRepo.GetAll()
                    .Where(x => x.WorkOrderId == request.WorkOrderId)
                    .OrderBy(x => x.Sequence)
                    .ToList();

                // 4. 获取所有分派信息
                var processIds = processes.Select(p => p.Id).ToList();
                var assigns = _workOrderAssignRepo.GetAll()
                    .Where(x => processIds.Contains(x.WorkOrderProcessId))
                    .ToList();

                // 5. 构建综合信息DTO
                var comprehensiveInfo = new WorkOrderComprehensiveInfoDto();

                // 5.1 映射工单详情
                comprehensiveInfo.WorkOrder = _mapper.Map<WorkOrderDetailDto>(workOrder);

                // 映射工序信息
                var processDtos = _mapper.Map<List<WorkOrderProcessDto>>(processes);
                foreach (var processDto in processDtos)
                {
                    var processAssigns = assigns.Where(a => a.WorkOrderProcessId == processDto.Id).ToList();
                    processDto.Assigns = _mapper.Map<List<WorkOrderAssignDto>>(processAssigns);
                }
                comprehensiveInfo.WorkOrder.Processes = processDtos;

                // 5.2 映射计划明细信息
                if (planItem != null)
                {
                    comprehensiveInfo.PlanItem = _mapper.Map<PlanItemDto>(planItem);
                }

                // 5.3 构建产品完整信息
                comprehensiveInfo.ProductInfo = BuildProductInfo(workOrder, planItem);

                // 5.4 构建工序进度统计
                comprehensiveInfo.ProcessProgress = BuildProcessProgressSummary(processes);

                // 5.5 构建分派统计信息
                comprehensiveInfo.AssignSummary = BuildAssignSummary(processes, assigns);

                res.Data = comprehensiveInfo;
                res.Code = ApiEnum.Success;
                res.Msg = "获取工单综合信息成功";
            }
            catch (Exception ex)
            {
                res.Code = ApiEnum.Error;
                res.Msg = $"获取工单综合信息失败：{ex.Message}";
            }

            return res;
        }

        /// <summary>
        /// 构建产品完整信息
        /// </summary>
        private ProductInfoDto BuildProductInfo(WorkOrderModel workOrder, PlanItemModel? planItem)
        {
            var productInfo = new ProductInfoDto
            {
                ProductCode = workOrder.ProductCode,
                ProductName = workOrder.ProductName,
                Spec = workOrder.Spec,
                Unit = workOrder.Unit,
                PlannedQuantityFromWorkOrder = workOrder.PlannedQuantity,
                ActualQuantity = workOrder.ActualQuantity,
                GoodQuantity = workOrder.GoodQuantity,
                BadQuantity = workOrder.BadQuantity
            };

            // 如果有关联的计划明细，补充计划信息
            if (planItem != null)
            {
                productInfo.PlannedQuantityFromPlan = planItem.Quantity;
                // 优先使用计划明细的产品信息（可能更准确）
                if (string.IsNullOrEmpty(productInfo.ProductCode))
                    productInfo.ProductCode = planItem.ProductCode;
                if (string.IsNullOrEmpty(productInfo.ProductName))
                    productInfo.ProductName = planItem.ProductName;
                if (string.IsNullOrEmpty(productInfo.Spec))
                    productInfo.Spec = planItem.Spec;
            }

            // 计算完成进度百分比
            var plannedQty = productInfo.PlannedQuantityFromWorkOrder ?? productInfo.PlannedQuantityFromPlan ?? 0;
            if (plannedQty > 0 && productInfo.ActualQuantity.HasValue)
            {
                productInfo.CompletionPercentage = Math.Round((decimal)productInfo.ActualQuantity.Value / plannedQty * 100, 2);
            }

            return productInfo;
        }

        /// <summary>
        /// 构建工序进度统计
        /// </summary>
        private ProcessProgressSummaryDto BuildProcessProgressSummary(List<WorkOrderProcessModel> processes)
        {
            var summary = new ProcessProgressSummaryDto
            {
                TotalProcesses = processes.Count
            };

            var completedProcesses = processes.Where(p => p.Status == "已完成").ToList();
            var inProgressProcesses = processes.Where(p => p.Status == "进行中").ToList();
            var pendingProcesses = processes.Where(p => p.Status == "未开始" || string.IsNullOrEmpty(p.Status)).ToList();

            summary.CompletedProcesses = completedProcesses.Count;
            summary.InProgressProcesses = inProgressProcesses.Count;
            summary.PendingProcesses = pendingProcesses.Count;

            // 计算进度百分比
            if (summary.TotalProcesses > 0)
            {
                summary.ProgressPercentage = Math.Round((decimal)summary.CompletedProcesses / summary.TotalProcesses * 100, 2);
            }

            // 找到当前工序（第一个进行中的工序，如果没有则是第一个未开始的工序）
            var currentProcess = inProgressProcesses.OrderBy(p => p.Sequence).FirstOrDefault() 
                ?? pendingProcesses.OrderBy(p => p.Sequence).FirstOrDefault();

            if (currentProcess != null)
            {
                summary.CurrentProcess = new CurrentProcessDto
                {
                    Id = currentProcess.Id,
                    ProcessCode = currentProcess.ProcessCode,
                    ProcessName = currentProcess.ProcessName,
                    Status = currentProcess.Status,
                    PlannedQuantity = currentProcess.PlannedQuantity,
                    ReportedQuantity = currentProcess.ReportedQuantity
                };
            }

            return summary;
        }

        /// <summary>
        /// 构建分派统计信息
        /// </summary>
        private AssignSummaryDto BuildAssignSummary(List<WorkOrderProcessModel> processes, List<WorkOrderAssignModel> assigns)
        {
            var summary = new AssignSummaryDto
            {
                TotalAssignQuantity = assigns.Sum(a => a.Quantity),
                AssignedEmployeeCount = assigns.Select(a => a.EmployeeId).Distinct().Count()
            };

            // 按工序分组统计分派信息
            var processAssigns = new List<ProcessAssignSummaryDto>();
            
            foreach (var process in processes)
            {
                var processAssignList = assigns.Where(a => a.WorkOrderProcessId == process.Id).ToList();
                
                if (processAssignList.Any())
                {
                    var processAssignSummary = new ProcessAssignSummaryDto
                    {
                        ProcessId = process.Id,
                        ProcessName = process.ProcessName,
                        AssignQuantity = processAssignList.Sum(a => a.Quantity),
                        EmployeeCount = processAssignList.Select(a => a.EmployeeId).Distinct().Count()
                    };

                    // 构建员工分派列表
                    processAssignSummary.EmployeeAssigns = processAssignList
                        .GroupBy(a => new { a.EmployeeId, a.EmployeeName })
                        .Select(g => new EmployeeAssignDto
                        {
                            EmployeeId = g.Key.EmployeeId,
                            EmployeeName = g.Key.EmployeeName,
                            Quantity = g.Sum(a => a.Quantity)
                        })
                        .ToList();

                    processAssigns.Add(processAssignSummary);
                }
            }

            summary.ProcessAssigns = processAssigns;
            return summary;
        }
    }
}
